package com.zjjt.dc.modules.datacatch.service.blh.impl;

import cn.hutool.core.util.IdUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.zjjt.dc.modules.datacatch.entity.blh.DcCatchDataBlhProductInfo;
import com.zjjt.dc.modules.datacatch.service.blh.IBLHDataCatchService;
import com.zjjt.dc.modules.datacatch.service.blh.IDcCatchDataBlhProductInfoService;
import com.zjjt.dc.modules.datacatch.util.api.client.BLHApiClient;
import com.zjjt.dc.modules.datacatch.util.api.config.BLHApiConfig;
import com.zjjt.dc.tools.download.file.action.DownloadFileAction;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 *
 * @Description: 爬取百利会商品数据
 */
@Slf4j
@Service
public class BLHDataCatchService implements IBLHDataCatchService {

    @Value("${bai-li-hui.origin}")
    private String origin;

    @Value("${bai-li-hui.App_id}")
    private String App_id;

    @Value("${bai-li-hui.App_key}")
    private String App_key;

    @Value("${bai-li-hui.timeout}")
    private Integer timeout;

    private BLHApiConfig cfg;


    @Autowired
    private IDcCatchDataBlhProductInfoService dcCatchDataBlhProductInfoService;

    /**
     * 计算字符串的MD5哈希值并转换为大写
     *
     * @param input 输入字符串
     * @return MD5哈希值的大写表示
     */
    private static String md5ToUpperCase(String input) {
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            byte[] hashBytes = md.digest(input.getBytes());
            StringBuilder hexString = new StringBuilder();
            for (byte b : hashBytes) {
                String hex = String.format("%02x", b);
                hexString.append(hex);
            }
            return hexString.toString().toUpperCase();
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException("MD5算法不可用", e);
        }
    }

    @Override
    public void updateGoodsDatas(int startIdx, int limitNum, List<String> goodsIds) {
        try {
            String token = getBLHToken();
            if (ObjectUtils.isEmpty(goodsIds)) {
                goodsIds = new ArrayList<>();
                String[] ids = getGoodsIdsFromApi(token).split(",");
                if (ids.length > 0) {
                    goodsIds.addAll(List.of(ids));
                }
            }
            AtomicInteger idx = new AtomicInteger();
            List<String> ids = new ArrayList<>();

            goodsIds.subList(startIdx, Math.min(startIdx + limitNum, goodsIds.size())).forEach(goodsId -> {
                log.info("索引：{}", idx.getAndIncrement());
                String goodsInfoResponse = getGoodsInfoFromApi(token, goodsId);
                DcCatchDataBlhProductInfo productInfo = JSONUtil.toBean(goodsInfoResponse, DcCatchDataBlhProductInfo.class);
                if (ObjectUtils.isNotEmpty(productInfo)) {
                    productInfo.setId(IdUtil.getDataCenterId(17l));
                    productInfo.setCreateBy(1L);
                    productInfo.setUpdateBy(1L);
                    productInfo.setProductName(URLDecoder.decode(productInfo.getProductName(), StandardCharsets.UTF_8));
                    productInfo.setColorName(URLDecoder.decode(productInfo.getColorName(), StandardCharsets.UTF_8));
                    productInfo.setSellPoint(URLDecoder.decode(productInfo.getSellPoint(), StandardCharsets.UTF_8));
                    productInfo.setCategoryName(URLDecoder.decode(productInfo.getCategoryName(), StandardCharsets.UTF_8));
                    productInfo.setBrand(URLDecoder.decode(productInfo.getBrand(), StandardCharsets.UTF_8));
                    productInfo.setProductInfos(URLDecoder.decode(productInfo.getProductInfos(), StandardCharsets.UTF_8));
                    productInfo.setAppIntroduce(URLDecoder.decode(productInfo.getAppIntroduce(), StandardCharsets.UTF_8));


                    boolean updateResult = dcCatchDataBlhProductInfoService.save(productInfo);

                    if (updateResult) {
                        ids.add(String.valueOf(productInfo.getId()));
                        log.info("更新商品数据成功：{}", productInfo.getItemId());
                    } else {
                        log.error("更新商品数据失败：{}", productInfo.getItemId());
                    }
                }
            });
            storeImages(ids);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("更新商品数据异常：{}", e.getMessage());
        }
    }

    /**
     * 下载存储图片
     *
     * @param ids
     */

    private void storeImages(List<String> ids) {
        ids.forEach(id -> {
            DcCatchDataBlhProductInfo info = dcCatchDataBlhProductInfoService.getById(id);
            if (ObjectUtils.isNotEmpty(info)) {
                Set<String> uniqueImages = new LinkedHashSet<>();
                uniqueImages.addAll(extractImageUrls(info.getProductImages()));
                uniqueImages.addAll(extractImageUrls(info.getImages()));
                uniqueImages.addAll(extractImageUrls(info.getProductInfos()));
                uniqueImages.addAll(extractImageUrls(info.getAppletIntroduce()));
                List<String> images = new ArrayList<>(uniqueImages);
                new DownloadFileAction("./download/blh/" + id).actionThreads(images);
            }
        });
    }

    /**
     * 正则匹配图片链接
     */
    public List<String> extractImageUrls(String htmlContent) {
        Set<String> uniqueUrls = new LinkedHashSet<>(); // 保持插入顺序
        Pattern pattern = Pattern.compile(
                "https?://[\\w\\-\\.\\/~]+\\.(jpg|jpeg|png|gif|webp)(?:\\?[\\w\\-\\.=;&%]*)?",
                Pattern.CASE_INSENSITIVE
        );
        Matcher matcher = pattern.matcher(htmlContent); // 创建匹配器
        while (matcher.find()) {
            uniqueUrls.add(matcher.group());
        }

        return new ArrayList<>(uniqueUrls);
    }

    private String getGoodsInfoFromApi(String token, String goodsId) {
        String result = null;
        try {
            JSONObject body = new JSONObject();
            body.set("token", token)
                    .set("itemId", goodsId);

            // 发送请求
            BLHApiClient client = new BLHApiClient(cfg);
            String responseBody = client.SendRequest("/Product/getGoodInfo", body.toString());

            JSONObject json = new JSONObject(responseBody);
            if (json.getBool("result")) {
                result = json.getJSONObject("data").getStr("product");
            } else {
                log.error("获取商品信息异常：{}", json.getStr("desc"));
            }
        } catch (Exception e) {
            log.error("获取商品信息异常：{}", e.getMessage());
        }
        return result;
    }

    private String getGoodsIdsFromApi(String token) {
        String result = null;
        try {
            JSONObject body = new JSONObject();
            body.set("token", token);

            // 发送请求
            BLHApiClient client = new BLHApiClient(cfg);
            String responseBody = client.SendRequest("/Product/getGoodsId", body.toString());

            JSONObject json = new JSONObject(responseBody);

            if (json.getBool("result")) {
                long num = json.getJSONObject("data").getLong("num");
                if (num > 0) {
                    result = json.getJSONObject("data").getStr("ids");
                }
            } else {
                log.error("获取商品Ids异常：{}", json.getStr("desc"));
            }

        } catch (Exception e) {
            log.error("获取商品Ids异常：{}", e.getMessage());
        }
        return result;
    }

    private String getBLHToken() {
        String result = null;
        try {
            if (ObjectUtils.isEmpty(cfg)) {
                cfg = new BLHApiConfig(origin, App_id, App_key, timeout);
            }
            String currentTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));

            JSONObject body = new JSONObject();
            body.put("app_id", App_id);
            body.put("app_key", App_key);
            body.put("tamptimes", currentTime);
            body.put("sign", buildSign(currentTime));

            // 发送请求
            BLHApiClient client = new BLHApiClient(cfg);
            String responseBody = client.SendRequest("/Index/getToken", body.toString());
            JSONObject json = new JSONObject(responseBody);
            if (json.getBool("result")) {
                result = json.getJSONObject("data").getStr("token");
            } else {
                log.error("获取token异常：{}", json.getStr("desc"));
            }
        } catch (Exception e) {
            log.error("获取token异常：{}", e.getMessage());
        }
        return result;
    }

    /**
     * 构建签名
     *
     * @param currentTime 当前时间字符串
     * @return 签名字符串
     */
    private String buildSign(String currentTime) throws NoSuchAlgorithmException {
        String sign = String.format("app_id=%s:app_key=%s:tamptimes=%s", App_id, App_key, currentTime);
        return md5ToUpperCase(sign);
    }
}
